﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Win32;

namespace 灵溪工具箱
{
    public partial class Frida : Window
    {
        public Frida()
        {
            InitializeComponent();
            LoadProcesses();
        }

        private void LoadProcesses()
        {
            try
            {
                List<string> processes = Process.GetProcesses().Select(p => p.ProcessName).Distinct().ToList();
                ProcessComboBox.ItemsSource = processes;
            }
            catch (Exception ex)
            {
                LogListBox.Items.Add($"加载进程失败: {ex.Message}");
            }
        }

        private void ProcessComboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (ProcessComboBox.SelectedItem != null)
            {
                string selectedProcessName = ProcessComboBox.SelectedItem.ToString();
                int pid = GetProcessIdByName(selectedProcessName);
                PidTextBox.Text = pid.ToString();
            }
        }

        private int GetProcessIdByName(string processName)
        {
            try
            {
                Process[] processes = Process.GetProcessesByName(processName);
                if (processes.Length > 0)
                {
                    return processes[0].Id;
                }
            }
            catch (Exception ex)
            {
                LogListBox.Items.Add($"获取进程ID失败: {ex.Message}");
            }
            return -1; 
        }

        private void OpenFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "JavaScript Files (*.js)|*.js|All Files (*.*)|*.*";
            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    string fileContent = File.ReadAllText(openFileDialog.FileName);
                    JsCodeEditor.Text = fileContent;
                }
                catch (Exception ex)
                {
                    LogListBox.Items.Add($"读取文件失败: {ex.Message}");
                }
            }
        }

        private async void RunScript_Click(object sender, RoutedEventArgs e)
        {
            string scriptContent = JsCodeEditor.Text;
            if (string.IsNullOrEmpty(scriptContent))
            {
                LogListBox.Items.Add("脚本内容为空，请先编写或打开一个脚本。");
                return;
            }

            string scriptPath = Path.Combine(Environment.CurrentDirectory, "Script", "script.js");

            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(scriptPath));
                File.WriteAllText(scriptPath, scriptContent);
                LogListBox.Items.Add($"脚本已保存到: {scriptPath}");
            }
            catch (Exception ex)
            {
                LogListBox.Items.Add($"保存脚本失败: {ex.Message}");
                return;
            }

            int pid;
            if (!int.TryParse(PidTextBox.Text, out pid) || pid <= 0)
            {
                LogListBox.Items.Add("无效的PID，请选择有效的进程。");
                return;
            }

            await Task.Run(() =>
            {
                try
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo
                    {
                        FileName = "frida",
                        Arguments = $"-p {pid} -l \"{scriptPath}\"",
                        RedirectStandardOutput = true,
                        RedirectStandardError = true,
                        UseShellExecute = false,
                        CreateNoWindow = true
                    };

                    using (Process process = Process.Start(startInfo))
                    {
                        using (System.IO.StreamReader outputReader = process.StandardOutput)
                        using (System.IO.StreamReader errorReader = process.StandardError)
                        {
                            while (!outputReader.EndOfStream)
                            {
                                string line = outputReader.ReadLine();
                                Dispatcher.Invoke(() => LogListBox.Items.Add(line));
                            }

                            while (!errorReader.EndOfStream)
                            {
                                string line = errorReader.ReadLine();
                                Dispatcher.Invoke(() => LogListBox.Items.Add(line));
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Dispatcher.Invoke(() => LogListBox.Items.Add($"运行Frida失败: {ex.Message}"));
                }
            });
        }

        private void CopyOutput_Click(object sender, RoutedEventArgs e)
        {
            if (LogListBox.Items.Count > 0)
            {
                string output = string.Join("\n", LogListBox.Items.Cast<object>().Select(item => item.ToString()));
                Clipboard.SetText(output);
                MessageBox.Show("输出已复制到剪贴板。", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else
            {
                MessageBox.Show("没有可复制的日志输出。", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }
    }
}